package org.hertsig.magiccardmarket.oauth;

import static com.google.common.base.Preconditions.checkNotNull;
import lombok.Getter;
import lombok.Setter;
import lombok.SneakyThrows;
import oauth.signpost.commonshttp.CommonsHttpOAuthConsumer;
import oauth.signpost.commonshttp.HttpRequestAdapter;
import oauth.signpost.exception.OAuthException;
import oauth.signpost.http.RequestParameters;

import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.impl.client.HttpClientBuilder;
import org.hertsig.magiccardmarket.MagicCardMarketApi;

/**
 * Allows a dedicated app to connect and send authenticated requests
 */
public class SignpostApi extends MagicCardMarketApi {
	@Getter private final HttpClient client = HttpClientBuilder.create()
			.setSSLSocketFactory(new SSLConnectionSocketFactory(createSslContext()))
			.build();
	private final SignpostOAuthConsumer consumer;
	
	public SignpostApi(String appToken, String appSecret, String accessToken, String accessTokenSecret) {
		this.consumer = new SignpostOAuthConsumer(appToken, appSecret);
		consumer.setTokenWithSecret(accessToken, accessTokenSecret);
	}
	
	@Override
	@SneakyThrows(OAuthException.class)
	protected void prepareRequest(HttpUriRequest request) {
		consumer.setUrl(request.getRequestLine().getUri());
		consumer.sign(new HttpRequestAdapter(request));
	}
	
	@Override
	protected String base() {
		return "https://sandbox.mkmapi.eu/ws/v1.1/";
	}
	
	private final class SignpostOAuthConsumer extends CommonsHttpOAuthConsumer {
		@Setter private String url;
		private static final long serialVersionUID = 1L;
		
		private SignpostOAuthConsumer(String consumerKey, String consumerSecret) {
			super(consumerKey, consumerSecret);
		}
		
		@Override
		protected void completeOAuthParameters(RequestParameters out) {
			super.completeOAuthParameters(out);
			out.put("realm", checkNotNull(url, "URL not set"));
			setUrl(null);
		}
	}
}
